#ifndef EXPR_H
#define EXPR_H

#include "ast.h"
#include "symbol.h"
#include <stdio.h>

struct expr {
	int kind;
	struct expr *left;
	struct expr *right;
	const char *name;
	int constant;
	struct symbol *symbol;
	int reg;
};

struct expr * expr_create( 
      int kind, 
      struct expr *left, 
      struct expr *right, 
      const char * name, 
      int constant, 
      struct symbol * symbol, 
      int reg);

void expr_print( struct expr * e ); 

void expr_resolve( struct expr *e, int print );
struct type * expr_typecheck( struct expr *e );
void expr_codegen( FILE *file, struct expr *e );
int lval_check(struct expr * e);
int isFunc(struct expr * e);

void expr_generate_strings(struct expr * e);
void expr_codegen_constant(FILE * file, struct expr * e);
int param_list_size(struct param_list * p);
void expr_gen_comparison(FILE * file, struct expr * e, const char * cmp);


#define EXPR_KIND_LT       0
#define EXPR_KIND_LE       1
#define EXPR_KIND_EQ       2
#define EXPR_KIND_NE       3
#define EXPR_KIND_GT       4
#define EXPR_KIND_GE       5
#define EXPR_KIND_NOT      6
#define EXPR_KIND_ADD      7
#define EXPR_KIND_SUB      8
#define EXPR_KIND_MUL      9
#define EXPR_KIND_DIV      10
#define EXPR_KIND_NEG      11
#define EXPR_KIND_MOD      12
#define EXPR_KIND_ASSIGN   13
#define EXPR_KIND_CALL     14
#define EXPR_KIND_ARG      15
#define EXPR_KIND_NAME     16
#define EXPR_KIND_INT      17
#define EXPR_KIND_CHAR     18
#define EXPR_KIND_BOOLEAN  19
#define EXPR_KIND_INCR     20
#define EXPR_KIND_DECR     21
#define EXPR_KIND_STRING       22
#define EXPR_KIND_LOGICALOR    23
#define EXPR_KIND_LOGICALAND   24
#define EXPR_KIND_POW          25

#endif
